<?php

namespace app\model;

use think\helper\Str;
use think\Model;
use think\model\relation\HasMany;
use think\model\relation\HasOne;

class Store extends Model
{
    public function supplier(): HasOne
    {
        return $this->hasOne(Supplier::class, 'id', 'pid');
    }

    public function proIts(): HasOne
    {
        return $this->hasOne(Area::class, "id", "pro");
    }

    public function cityIts(): HasOne
    {
        return $this->hasOne(Area::class, "id", "city");
    }

    public function areaIts(): HasOne
    {
        return $this->hasOne(Area::class, "id", "area");
    }

    public function streetIts()
    {
        return $this->hasOne(Area::class, "id", "street");
    }

    public function getPage(): array
    {
        $params = request()->get();
        $page = $params['page'] ?? 1;
        $limit = $params['limit'] ?? 50;
        $data = $this->with(['supplier', 'proIts', 'cityIts', 'areaIts', 'streetIts'])->when(!empty($params['name']), function ($query) use ($params) {
            $query->whereLike('name|username', '%' . $params['name'] . '%');
        })->when(!empty($params['state']), function ($query) use ($params) {
            $query->where('state', $params['state']);
        })->when(!empty($params['mobile']), function ($query) use ($params) {
            $query->where('mobile', $params['mobile']);
        })->when(!empty($params['pid']), function ($query) use ($params) {
            $query->where('pid', $params['pid']);
        })->when(!empty($params['id']), function ($query) use ($params) {
            $query->where('id', $params['id']);
        })->when(!empty($params['cityTree']), function ($query) use ($params) {
//            $query->where('cityTree', $params['cityTree']);
            $c = ['pro' => $params['cityTree'][0]];
            if (!empty($params['cityTree'][1])) {
                $c['city'] = $params['cityTree'][1];
            }
            if (!empty($params['cityTree'][2])) {
                $c['area'] = $params['cityTree'][2];
            }

            if (!empty($params['cityTree'][3])) {
                $c['street'] = $params['cityTree'][3];
            }
            $query->where($c);
        })->where(['is_del' => 1])->order(['create_time' => 'desc'])->paginate(['list_rows' => $limit, 'page' => $page])->toArray();
        $store = app(Account::class);
        if (!empty($data['data'])) {
            foreach ($data['data'] as &$v) {
                //统计余额
                $balance = $store->where(['store_id' => $v['id'], 'type' => 3, 'is_del' => 1])->sum('balance');
                $storeAccountBalance = $store->where(['store_id' => $v['id'], 'type' => 2, 'is_del' => 1])->where('balance', '>', 0)->value('balance');
                $v['st_balance'] = bcadd(($balance ?? 0), ($storeAccountBalance ?? 0), 2);
            }
        }
        return ['total' => $data['total'], 'lst' => $data['data']];
    }

    public function detail()
    {
        $id = request()->param("id");
        $data = $this->findOrFail($id);
        $data->content = htmlspecialchars_decode($data->content);
        $data->changeCity = array_values(array_filter([$data->pro, $data->city, $data->area, $data->street]));
        return $data;
    }

    public function updateOrAdd(): array
    {
        $param = request()->param();
        $param['content'] = htmlentities($param['content']);
        if (!empty($param['changeCity'])) {
            $param['pro'] = $param['changeCity'][0];
            $param['city'] = $param['changeCity'][1] ?? null;
            $param['area'] = $param['changeCity'][2] ?? null;
            $param['street'] = $param['changeCity'][3] ?? null;
        }
        unset($param['create_time'], $param['update_time'],
            $param['changeCity']);
        $this->startTrans();
        $this->exists(!empty($param['id']))->save($param);
        if (empty($param['id'])) {
            //新增渠道账号
            $account = app(Account::class);
            $mobile = $account->where(['account' => $param['mobile'], 'is_del' => 1])->count();
            $_account = $param['mobile'];
            if ($mobile > 0) {
                //将字符按长度分割成数组
                $arr = str_split($param['mobile'], 1);
                $_account .= bcadd(bcadd(bcadd($this->id, 1000), array_sum($arr)), rand(100, 999));
            }
            $password = setPassword("123456");
            $account->save([
                'name' => $param['username'],
                'supplier_id' => $this->pid,
                'store_id' => $this->id,
                'type' => 2,
                'balance' => 0,
                'mobile' => $param['mobile'],
                'is_del' => 1,
                'state' => 1,
                'password' => $password['password'],
                'decode' => $password['encode'],
                'account' => $_account
            ]);
        }
        $this->commit();
        return $this->toArray();
    }

    public function addBalance(): array
    {
        $param = request()->post();
        $this->startTrans();
        $auth = getAuthorization();
        if ($param['type'] == 1) {
            $this->where(['id' => $param['id']])->inc("balance", bcmul($param['addBalance'], 100))->save();
            app(BalanceNotice::class)->save([
                'store_id' => $param['id'],
                'supplier_id' => $param['pid'],
                'aid' => $auth['id'],
                'content' => '预存金' . $param['addBalance'] . '元',
                'number' => bcmul($param['addBalance'], 100),
                'type' => 1
            ]);
            //门店账号加款
            app(Account::class)->where(['store_id' => $param['id'], 'type' => 2])->inc('balance', bcmul($param['addBalance'], 100))->save();
        } else {
            $this->where(['id' => $param['id']])->inc("coupon_balance", bcmul($param['addBalance'], 100))->save();
            app(CouponBalanceNotice::class)->save([
                'store_id' => $param['id'],
                'supplier_id' => $param['pid'],
                'aid' => $auth['id'],
                'content' => '预存金' . $param['addBalance'] . '元',
                'number' => bcmul($param['addBalance'], 100),
                'type' => 1
            ]);
        }
        $this->commit();
        return $this->toArray();
    }

    public function subBalance(): array
    {
        $param = request()->post();
        $this->startTrans();
        $auth = getAuthorization();
        if ($param['type'] == 1) {
            $this->where(['id' => $param['id']])->dec("balance", bcmul($param['addBalance'], 100))->save();
            app(BalanceNotice::class)->save([
                'store_id' => $param['id'],
                'supplier_id' => $param['pid'],
                'aid' => $auth['id'],
                'content' => '退款' . $param['addBalance'] . '元',
                'number' => bcmul($param['addBalance'], 100),
                'type' => 3
            ]);
            //店长账号退款
            app(Account::class)->where(['store_id' => $param['id'], 'type' => 2, 'is_del' => 1])->dec('balance', bcmul($param['addBalance'], 100))->save();
        } else {
            $this->where(['id' => $param['id']])->dec("coupon_balance", bcmul($param['addBalance'], 100))->save();
            app(CouponBalanceNotice::class)->save([
                'store_id' => $param['id'],
                'supplier_id' => $param['pid'],
                'aid' => $auth['id'],
                'content' => '退款' . $param['addBalance'] . '元',
                'number' => bcmul($param['addBalance'], 100),
                'type' => 3
            ]);
        }

        $this->commit();
        return $this->toArray();
    }

    public function del()
    {
        $id = request()->param("id");
        $data = $this->find($id);
        if (empty($data)) throw new \Exception("数据不存在", 7023);
        if ($data->balance > 0) throw new \Exception("预存金不为0，无法删除", 7023);
        $data->startTrans();
        $data->is_del = 0;
        $data->save();
        app(Account::class)->where(['store_id' => $id])->save(['is_del' => 0]);
        $data->commit();
        return $data->toArray();
    }

    public function getStore(): array
    {
        $admin = request()->admin;
        return $this->where(['is_del' => 1, 'state' => 1])->when(!empty($admin) && $admin['is_admin'] == 2, function ($query) {
            $query->where('id', '<>', 13);
        })->column("id,name");
    }

    public function merchantStore(): array
    {
        $auth = getAuthorization();
        $supplier = app(Account::class)->where(['id' => $auth['id']])->value("supplier_id");
        return $this->where(['is_del' => 1, 'state' => 1, 'pid' => $supplier])->column("id,name");
    }

    public function invoice(): HasMany
    {
        return $this->hasMany(Invoice::class, "sid")->where('state', '=', 1);
    }

    public function addRecharge(): HasMany
    {
        return $this->hasMany(BalanceNotice::class, 'store_id')->where(['type' => 1]);
    }

    public function subRecharge(): HasMany
    {
        return $this->hasMany(BalanceNotice::class, 'store_id')->where('type', '<>', 1);
    }

    public function invoiceData($store_id): array
    {
        $data = $this->withSum(['addRecharge' => 'add'], 'number')->withSum(['subRecharge' => 'sub'], 'number')->withSum(['invoice' => 'out'], 'money')->where('invo', '=', 1)->whereIn('id', $store_id)->paginate(['list_rows' => request()->param("limit", 50), 'page' => request()->param('page', 1)])->toArray();
        if (!empty($data['data'])) {
            $model = app(Account::class);
            $balance = $model->where(['type' => 3, 'is_del' => 1])->where('supplier_id', '<>', 5)->field("store_id,sum(balance) money")->group('store_id')->select()->toArray();
            if (!empty($balance)) $balance = array_column($balance, 'money', 'store_id');
        }
        return ['total' => $data['total'], 'lst' => array_map(function ($item) use ($balance) {
            return $this->extracted($item, $balance[$item['id']] ?? 0);
        }, $data['data']), 'last_page' => $data['last_page']];
    }

    public function invoiceChat(): array
    {
        $store_id = app(BalanceNotice::class)->where('store_id','<>',13)->group('store_id')->column('store_id');
        $data = $this->withSum(['addRecharge' => 'add'], 'number')->withSum(['subRecharge' => 'sub'], 'number')->withSum(['invoice' => 'out'], 'money')->where('invo', '=', 1)->whereIn('id', $store_id)->select()->toArray();
        $items = [
            "recharge" => 0,
            "invoice" => 0,
            "into" => 0,
            "balance" => 0
        ];
        $model = app(Account::class);
        $balance = $model->where(['type' => 3, 'is_del' => 1])->where('supplier_id', '<>', 5)->field("store_id,sum(balance) money")->group('store_id')->select()->toArray();
        if (!empty($balance)) $balance = array_column($balance, 'money', 'store_id');
        foreach ($data as $value) {
            $value = $this->extracted($value, $balance[$value['id']] ?? 0);
            $items['recharge'] += $value['total'];
            $items['invoice'] += $value['out'];
            $items['into'] += $value['into'];
            $items['balance'] += $value['balance'];
        }
        return $items;
    }

    public function invoiceDownload($store_id): array
    {
        $data = $this->invoiceData($store_id);
        $result = array_map(function ($item) {
            return [
                $item['name'],
                $item['total'],
                $item['out'],
                $item['into'],
                $item['balance']
            ];
        }, $data['lst']);

        $totalPage = $data['last_page'];
        $header = ['门店名称', '充值金额', '已开票金额', '未开票金额', '门店余额'];
        $title = ["开票记录"];
        $file = "开票记录";
        return compact("result", "header", "title", "totalPage", "file");
    }

    /**
     * @param mixed $value
     * @param $balance
     */
    public function extracted($value, $balance)
    {
        $value['add'] = $value['add'] > 0 ? (float)bcdiv($value['add'], 100, 2) : 0;
        $value['sub'] = $value['sub'] > 0 ? (float)bcdiv($value['sub'], 100, 2) : 0;
        if ($value['out'] && $value['out'] > 0) $value['out'] = (float)bcdiv($value['out'], 100, 2);
        else $value['out'] = 0;
        $value['total'] = (float)bcsub($value['add'], $value['sub'], 2);
        $value['into'] = (float)bcsub($value['total'], $value['out'], 2);
        unset($value['add'], $value['sub']);
        //获取到店长账号余额
//        if()
        $money = bcadd($value['balance'], $balance ?? 0, 2);
        $value['balance'] = (float)bcdiv($money, 100, 2);
        return $value;
    }
}
